package com.heima.a07_demo.server.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.heima.a07_demo.pojo.entity.DiagnosisRecord;
import com.heima.a07_demo.pojo.entity.DiagnosisResult;
import com.heima.a07_demo.pojo.entity.Patient;
import com.heima.a07_demo.pojo.vo.*;
import com.heima.a07_demo.server.mapper.DiagnosisRecordMapper;
import com.heima.a07_demo.server.mapper.DiagnosisResultMapper;
import com.heima.a07_demo.server.mapper.PatientMapper;
import com.heima.a07_demo.server.service.DiagnosisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.core.type.TypeReference;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class DiagnosisServiceImpl implements DiagnosisService {
    @Autowired
    private PatientMapper patientMapper;
    @Autowired
    private DiagnosisRecordMapper diagnosisRecordMapper;
    @Autowired
    private DiagnosisResultMapper diagnosisResultMapper;
    private ObjectMapper objectMapper = new ObjectMapper();
    /*、
     * 模型函数
     * */
    private  RestTemplate restTemplate = new RestTemplate();

    public Map<String, Object> callDeepLearning (ArrayList < String > imagePaths) {
        String flaskUrl = "http://192.168.239.194:5000/diagnose";
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("imagePaths", imagePaths);
        ResponseEntity<Map> response = restTemplate.postForEntity(flaskUrl, requestBody, Map.class);
        return response.getBody();
    }
    public String check(String result){
        if(result.equals("N")){
            result="正常";
        }
        if(result.equals("D")){
            result="糖尿病";
        }
        if(result.equals("G")){
            result="青光眼";
        }
        if(result.equals("C")){
            result="白内障";
        }
        if(result.equals("A")){
            result="AMD";
        }
        if(result.equals("H")){
            result="高血压";
        }
        if(result.equals("M")){
            result="近视";
        }
        if(result.equals("O")){
            result="其他疾病/异常";
        }
        return result;
    }

    @Transactional
    @Override
    public DiagnosisVO diagnosis(Long patientId, Long doctorId, ArrayList<String> imagePaths) {
        //调用模型，获取模型返回结果
        Map<String, Object> resultMap = callDeepLearning(imagePaths);
        //返回封装结果
        List<Map<String, Object>> results = (List<Map<String, Object>>) resultMap.get("results");

        Map<String, Object> leftResultMap = results.get(0);
        Map<String, Object> rightResultMap = results.get(1);
        String imageLeft = imagePaths.get(0);
        String imageRight = imagePaths.get(1);

        ArrayList<String> leftLabels = (ArrayList<String>) leftResultMap.get("labels");
        ArrayList<Double> leftProbabilities = (ArrayList<Double>) leftResultMap.get("probabilities");
        ArrayList<String> rightLabels = (ArrayList<String>) rightResultMap.get("labels");
        ArrayList<Double> rightProbabilities = (ArrayList<Double>) rightResultMap.get("probabilities");

        String leftResult = leftLabels.get(0);
        leftResult="左眼"+check(leftResult);
        Double leftConfidence=leftProbabilities.get(0);
        Double rightConfidence=rightProbabilities.get(0);
        String rightResult = rightLabels.get(0);
        rightResult="右眼"+check(rightResult);
        String finalResult = leftResult + "," + rightResult;
        DiagnosisResultVO diseaseLeft = new DiagnosisResultVO(leftLabels, leftProbabilities);
        DiagnosisResultVO diseaseRight = new DiagnosisResultVO(rightLabels, rightProbabilities);

        DiagnosisVO diagnosisVO = new DiagnosisVO(imageLeft, imageRight, patientId, leftResult, rightResult, finalResult, diseaseLeft, diseaseRight);
    //保存诊断记录

        DiagnosisRecord diagnosisRecord=new DiagnosisRecord();
        diagnosisRecord.setDoctorId(doctorId);
        diagnosisRecord.setPatientId(patientId);
        diagnosisRecord.setLeftResult(leftResult);
        diagnosisRecord.setRightResult(rightResult);
        diagnosisRecord.setFinalResult(finalResult);
        diagnosisRecord.setLeftConfidence(leftConfidence);
        diagnosisRecord.setRightConfidence(rightConfidence);
        diagnosisRecord.setDiagnosisTime(LocalDateTime.now());

        diagnosisRecordMapper.save(diagnosisRecord); // 直接调用，无需接收返回值
        System.out.println("自动生成的 recordId: " + diagnosisRecord.getRecordId());

    //修改患者信息
        Patient patient=new Patient();
        //根据患者id查询患者信息
        patient=patientMapper.getById(patientId);
        patient.setRecordId(diagnosisRecord.getRecordId());
        patient.setLeftResult(leftResult);
        patient.setRightResult(rightResult);
        patient.setFinalResult(finalResult);
        patient.setDiagnosisTime(LocalDateTime.now());
        patientMapper.save(patient);
    //将诊断结果保存
        DiagnosisResult diagnosisResult=new DiagnosisResult();
        diagnosisResult.setRecordId(diagnosisRecord.getRecordId());
        diagnosisResult.setImageLeft(imageLeft);
        diagnosisResult.setImageRight(imageRight);
        diagnosisResult.setPatientId(patientId);
        diagnosisResult.setDoctorId(doctorId);
        diagnosisResult.setLeftResult(leftResult);
        diagnosisResult.setRightResult(rightResult);
        diagnosisResult.setFinalResult(finalResult);
        diagnosisResult.setCreateTime(LocalDateTime.now());

        try {
            diagnosisResult.setDiseaseLeftLabels(objectMapper.writeValueAsString(leftLabels));
            diagnosisResult.setDiseaseLeftProbabilities(objectMapper.writeValueAsString(leftProbabilities));
            diagnosisResult.setDiseaseRightLabels(objectMapper.writeValueAsString(rightLabels));
            diagnosisResult.setDiseaseRightProbabilities(objectMapper.writeValueAsString(rightProbabilities));
        } catch (JsonProcessingException e) {
            throw new RuntimeException("Failed to convert lists to JSON strings", e);
        }
        diagnosisResultMapper.save(diagnosisResult);
        return diagnosisVO;
    }
    /*
     * 批量诊断
     * */

    @Transactional
    @Override
    public ArrayList<DiagnosisVO> diagnosisBatch(ArrayList<Long> patientIds, Long doctorId,
                                                 ArrayList<String> imagePaths) {
        // 调用深度学习服务获取所有结果
        Map<String, Object> resultMap =callDeepLearning(imagePaths);
        List<Map<String, Object>> allResults = (List<Map<String, Object>>) resultMap.get("results");
        ArrayList<DiagnosisVO> diagnosisList = new ArrayList<>();
        // 按每两个结果为一组处理
        for (int i = 0; i < patientIds.size(); i++) {
            Long patientId = patientIds.get(i);
            int leftIndex = i * 2;
            int rightIndex = i * 2 + 1;
            // 获取当前患者的左右眼图像路径
            String imageLeft = imagePaths.get(leftIndex);
            String imageRight = imagePaths.get(rightIndex);

            // 获取当前患者的左右眼诊断结果
            Map<String, Object> leftResultMap = allResults.get(leftIndex);
            Map<String, Object> rightResultMap = allResults.get(rightIndex);

            DiagnosisResultVO diseaseLeft = new DiagnosisResultVO(
                    (ArrayList<String>) leftResultMap.get("labels"),
                    (ArrayList<Double>) leftResultMap.get("probabilities")
            );

            DiagnosisResultVO diseaseRight = new DiagnosisResultVO(
                    (ArrayList<String>) rightResultMap.get("labels"),
                    (ArrayList<Double>) rightResultMap.get("probabilities")
            );

            String leftResult = diseaseLeft.getLabels().get(0);
            leftResult="左眼"+check(leftResult);
            String rightResult = diseaseRight.getLabels().get(0);
            rightResult="右眼"+check(rightResult);
            String finalResult = leftResult + "," + rightResult;
            Double leftConfidence=diseaseLeft.getProbabilities().get(0);
            Double rightConfidence=diseaseRight.getProbabilities().get(0);
            DiagnosisVO diagnosisVO = new DiagnosisVO(
                    imageLeft,
                    imageRight,
                    patientId,
                    leftResult,
                    rightResult,
                    finalResult,
                    diseaseLeft,
                    diseaseRight
            );
            //保存诊断记录

            DiagnosisRecord diagnosisRecord=new DiagnosisRecord();
            diagnosisRecord.setDoctorId(doctorId);
            diagnosisRecord.setPatientId(patientId);
            diagnosisRecord.setLeftResult(leftResult);
            diagnosisRecord.setRightResult(rightResult);
            diagnosisRecord.setFinalResult(finalResult);
            diagnosisRecord.setLeftConfidence(leftConfidence);
            diagnosisRecord.setRightConfidence(rightConfidence);
            diagnosisRecord.setDiagnosisTime(LocalDateTime.now());

            diagnosisRecordMapper.save(diagnosisRecord); // 直接调用，无需接收返回值

            System.out.println("自动生成的 recordId: " + diagnosisRecord.getRecordId());


            //修改患者信息
            Patient patient=new Patient();
            //根据患者id查询患者信息
            patient=patientMapper.getById(patientId);
            patient.setRecordId(diagnosisRecord.getRecordId());
            patient.setLeftResult(leftResult);
            patient.setRightResult(rightResult);
            patient.setFinalResult(finalResult);
            patient.setDiagnosisTime(LocalDateTime.now());
            patientMapper.save(patient);
            //将诊断结果保存
            DiagnosisResult diagnosisResult=new DiagnosisResult();
            diagnosisResult.setRecordId(diagnosisRecord.getRecordId());
            diagnosisResult.setImageLeft(imageLeft);
            diagnosisResult.setImageRight(imageRight);
            diagnosisResult.setPatientId(patientId);
            diagnosisResult.setDoctorId(doctorId);
            diagnosisResult.setLeftResult(leftResult);
            diagnosisResult.setRightResult(rightResult);
            diagnosisResult.setFinalResult(finalResult);
            diagnosisResult.setCreateTime(LocalDateTime.now());

            try {
                diagnosisResult.setDiseaseLeftLabels(objectMapper.writeValueAsString(diseaseLeft.getLabels()));
                diagnosisResult.setDiseaseLeftProbabilities(objectMapper.writeValueAsString(diseaseLeft.getProbabilities()));
                diagnosisResult.setDiseaseRightLabels(objectMapper.writeValueAsString(diseaseRight.getLabels()));
                diagnosisResult.setDiseaseRightProbabilities(objectMapper.writeValueAsString(diseaseRight.getProbabilities()));
            } catch (JsonProcessingException e) {
                throw new RuntimeException("Failed to convert lists to JSON strings", e);
            }
            diagnosisResultMapper.save(diagnosisResult);

            diagnosisList.add(diagnosisVO);
        }

        return diagnosisList;
    }
    /*
    * 返回诊断报告
    * */
    @Override
    public DiagnosisReportVO getDiagnosisReport(Long patientId) {
        Patient patient = patientMapper.getById(patientId);
        DiagnosisResult diagnosisResult = diagnosisResultMapper.getLatestDiagnosisResultByPatientId(patientId);

        PatientMsg patientMsg = new PatientMsg(
                patient.getName(),
                patient.getGender(),
                patient.getAge(),
                patient.getPatientId(),
                patient.getDiagnosisTime()
        );

        ArrayList<String> diseaseLeftLabels = null;
        ArrayList<Double> diseaseLeftProbabilities = null;
        ArrayList<String> diseaseRightLabels = null;
        ArrayList<Double> diseaseRightProbabilities = null;

        try {
            diseaseLeftLabels = objectMapper.readValue(diagnosisResult.getDiseaseLeftLabels(), new TypeReference<ArrayList<String>>() {});
            diseaseLeftProbabilities = objectMapper.readValue(diagnosisResult.getDiseaseLeftProbabilities(), new TypeReference<ArrayList<Double>>() {});
            diseaseRightLabels = objectMapper.readValue(diagnosisResult.getDiseaseRightLabels(), new TypeReference<ArrayList<String>>() {});
            diseaseRightProbabilities = objectMapper.readValue(diagnosisResult.getDiseaseRightProbabilities(), new TypeReference<ArrayList<Double>>() {});
        } catch (Exception e) {
            e.printStackTrace();
        }

        ReportResult reportResult = new ReportResult(
                diagnosisResult.getImageLeft(),
                diagnosisResult.getImageRight(),
                diseaseLeftLabels,
                diseaseLeftProbabilities,
                diseaseRightLabels,
                diseaseRightProbabilities,
                diagnosisResult.getLeftResult(),
                diagnosisResult.getRightResult(),
                diagnosisResult.getFinalResult()
        );

        return new DiagnosisReportVO(patientMsg, reportResult);
    }

    /*
    * 分页查询诊断报告
    * */
    @Override
    public DiagnosisRecordPageVO selectDiagnosisRecordByPage(
            String beginTime,
            String endTime,
            String diagnosisType,
            int page,
            int pageSize
    ) {
        int offset = (page - 1) * pageSize;
        List<DiagnosisRecordVO> records = diagnosisRecordMapper.selectDiagnosisRecordByPage(
                beginTime,
                endTime,
                diagnosisType,
                offset,
                pageSize
        );
        Long total = diagnosisRecordMapper.selectDiagnosisRecordCount(
                beginTime,
                endTime,
                diagnosisType
        );
        return new DiagnosisRecordPageVO(total, records);
    }
    }
